<?php
/**
 * Constant - ver 0.7 : 29.IV.2009r;
 * Obsługuje stałe projektu przechowiwane w jego konfiguracji /projects/nazwa projektu/conf/project-conf.xml
 * Obsługa poprzez wykorzystanie funkcji projektu server/standardModels/org/arrowplatform/engine/projects/ArrowProject.php
 *
 * Jeśli grupa jest 0 to zarządzać tą stałą może tylko developer
 *
 */

final class ArrowSettings implements  IArrowSingleton,  IArrowCacheable {

	/**
	 * Array of all settings loaded from XML
	 * @var array
	 */
	private $data = array();
	/**
	 * Default instance
	 * @var object
	 */
	private static $instance = null ;
	
	private $projectReference = null;
	
	private $xmlDoc = null;
	
	/**
	 * Initialize settings system.
	 * @param $data
	 */
	public static function initialize( ArrowProject $projectReference, $data ) {
		self::getDefault($projectReference, $data);
	}
	
	/**
	 * Returns default (dummy) setting object which can be used to access settings
	 * @return ArrowSettings
	 */
	public static function getDefault( $projectReference = null, $data = null ){
		if( self::$instance == null || $data != null ) {
			self::$instance = new ArrowSettings() ;
			self::$instance->projectReference = $projectReference;
			self::$instance->data = $data;
		}
		return self::$instance ;
	}
	
	/**
	 * Cache generation
	 * @see IArrowCacheable::generateCache()
	 */
	public function generateCache( $xmlSections ) {
		$ret = array() ;
		foreach( $xmlSections as $xmlSection){
		
			foreach( $xmlSection->setting as $setting ) {  // dla każdej stałej
				$val = array();
				$cnst = explode( '.', (string) $setting->name ) ;	// umiesc ją odpowiednio w tablicy
				$parent = &$ret ;
				foreach( $cnst as $c ) {
					if( !isset( $parent[ $c ] ) ) {
						$parent[ $c ] = array();
					}
					$parent = &$parent[ $c ] ;
				}
				
				if( ((string) $setting->type) == "array"){
					$parent = explode( "|", (string) $setting->value);		
				}else{
					$parent = (string) $setting->value;
				}
			}
		}
		return $ret ;
	}

	public function getSetting($path){
	
		if($path == "")
			return $this->data;
		
		$levels = explode( ".", $path );
		
		$el = $this->data;
				
		foreach($levels as $level){
			if(isset($el[$level]))
				$el = $el[$level];
			else
				throw new ArrowProjectsException( array( "msg" => "[ArrowSetting::getSetting] Setting doesn't exist [$path] " ) );
		}
		return $el;
	}
	
	public function getConfiguration(){
		if($this->xmlDoc == null)
			$this->xmlDoc = $this->projectReference->getXMLConfig(ArrowProject::PROJECT_CONF_FILE);
			
		$settings = $this->xmlDoc->xpath("/project/settings/section/setting");
		
		$tmp = array();
		foreach($settings as $setting){
			$tmp["".$setting->name] = $this->getSettingExtentdedData("".$setting->name);
		}
		
		return $tmp;
	}
	
	public function getSettingExtentdedData($path){
		if($this->xmlDoc == null)
			$this->xmlDoc = $this->projectReference->getXMLConfig(ArrowProject::PROJECT_CONF_FILE);
		
		$setting = $this->xmlDoc->xpath("/project/settings/section/setting[name='$path']");
		
		if($setting){
			$val = array();
			$setting = $setting[0];
			$parent = $setting->xpath('parent::*');
			
			$val["section"] = (string) $parent[0]["name"];
			$val["value"] = (string) $setting->value;
			$val["description"] = (string) $setting->description;
			$val["type"] = (string) $setting->type ;
			
			$val["options"] = array();
			foreach($setting->options->option as $option){
				$val["options"][(string) $option["value"]] = (string) $option["label"];
			} 
			
			$val["name"] = (string) $setting->name;
			$val["title"] = (string) $setting->title;
			
			if( isset($setting->groups) )
			$val["groups"] = (int) $setting->groups;
			else $val["groups"] = -1 ;
			return $val;
		}else{
			return false;
			
		}
	}


	public function setSettingValue($name, $val){
		if($this->xmlDoc == null)
			$this->xmlDoc = $this->projectReference->getXMLConfig(ArrowProject::PROJECT_CONF_FILE);
		
		$setting = $this->xmlDoc->xpath("/project/settings/section/setting[name='$name']");
		if(is_array($val))
			$val = implode("|", $val);
			
		if(isset($setting[0]->value))
			$setting[0]->value = $val;
			
		$this->xmlDoc = $this->projectReference->saveXMLConfig(ArrowProject::PROJECT_CONF_FILE, $this->xmlDoc);
	}
	
	public static function validate( $type, $value ) {
		$ret = false ;
		switch( $type ) {
			case "number": {
				$ret = is_numeric( $value );
			} break;
		}
		return $ret ;
	}
	
}
?>